/**
 * Created by zhangguoyu on 16/4/25.
 */

var Config = require('../models/Config');
var co = require('co');
var Utils = require('../utils/Utils');

var Editor = function (name) {
  this._cached = {};
  this.$name = name;
};

Editor.prototype.put = function (key, value) {
  this._cached[key] = value;
  return this;
};

Editor.prototype.commit = function (callback) {
  var self = this;
  return new Promise(function (resolve, reject) {
    co(function * () {
      var result = yield Config.update({ name: self.$name }, { '$set': { values: self._cached }}).exec();
      if (Utils.isFunction(callback)) {
        callback.call(self, undefined, result);
      }
      resolve(result);
    }).catch(function (err) {
      if (Utils.isFunction(callback)) {
        callback.call(self, err);
      }
      reject(err);
    });
  });
};

var Configuration = function (app, context) {
  this.$app = app;
  this.$context = context;
  this.$name = 'global';
};

Configuration.Editor = Editor;

Configuration.prototype.getConfig = function (name) {
  var config = new Configuration(this.$app, this.$context);
  config.$name = name;
  return config;
};

Configuration.prototype.get = function (key, defaultValue, callback) {
  var self = this;
  if (Utils.isFunction(defaultValue)) {
    callback = defaultValue;
    defaultValue = undefined;
  }
  return new Promise(function (resolve, reject) {
    co(function * () {
      var lookup = { name: self.$name };
      var result = yield Config.findOne(lookup).exec();
      var val = undefined;
      if (result && result.values && result.values[key]) {
        val = result.values[key];
      } else if (!result) {
        lookup.values = {};
        var doc = new Config(lookup);
        yield doc.save();
      }
      if (!val && defaultValue !== undefined) {
        val = defaultValue;
      }
      if (val === undefined) {
        val = '';
      }
      if (Utils.isFunction(callback)) {
        callback.call(self, undefined, val);
      }
      resolve(val);
    }).catch(function (err) {
      if (Utils.isFunction(callback)) {
        callback.call(self, err);
      }
      reject(err);
    });
  });
};

Configuration.prototype.editor = function () {
  return new Editor(this.$name);
};

module.exports = Configuration;